/*
This file is part of MMM.

MMM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MMM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MMM.  If not, see <http://www.gnu.org/licenses/>.
*
* @package    MMM
* @author     Nikolaus Vahrenkamp
* @copyright  2013 High Performance Humanoid Technologies (H2T), Karlsruhe, Germany
*
*/

#ifndef _MMM_ConverterFactory_h_
#define _MMM_ConverterFactory_h_

#include "../../../MMMCore.h"
#include "../../../AbstractFactoryMethod.h"
#include "../../../MMMImportExport.h"
#include "Converter.h"
#include <boost/shared_ptr.hpp>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>

namespace MMM
{

/*!
	This Factory is used to make custom converters accessible by the MMM framework.
	An exemplary implementation may look like this
	
	\code

	// The header MyCustomConverterFactory.h

	namespace MMM 
	{

	class MMM_IMPORT_EXPORT MyCustomConverterFactory  : public ConverterFactory
	{
	public:
	EIGEN_MAKE_ALIGNED_OPERATOR_NEW

		MyConverterFactory() ;

		virtual ~MyConverterFactory();

		virtual ConverterPtr createConverter();

		static std::string getName() {return "MyCustomConverterFactory"};

		static boost::shared_ptr<ConverterFactory> createInstance(void*);

	private:
		static SubClassRegistry registry;
	};
	
	typedef boost::shared_ptr<MyCustomConverterFactory> MyCustomConverterFactoryPtr;

	}
	\endcode

	\code
	// The source MyCustomConverterFactory.cpp
	#include "MyCustomConverterFactory.h"
	#include <boost/extension/shared_library.hpp>
	#include <boost/function.hpp>

	namespace MMM
	{

	// register this factory, so that is accessible within the API
	ConverterFactory::SubClassRegistry MyCustomConverterFactory::registry(MyCustomConverterFactory::getName(), &MyCustomConverterFactory::createInstance);

	MyConverterFactory::MyConverterFactory()
	{
		// some init code
	}
	MyConverterFactory::~MyConverterFactory()
	{
		// some exit code
	}

	ConverterPtr MyConverterFactory::createConverter()
	{
		ConverterPtr converter(new MyCustomConverter());
		return converter;
	}

	boost::shared_ptr<ConverterFactory> MyConverterFactory::createInstance(void*)
	{
		boost::shared_ptr<ConverterFactory> converterFactory(new MyCustomConverterFactory());
		return converterFactory;
	}
	
	}

	// Enable Plugin mechanism, that allows the MMMConverter tool to load this converter
	// The MMMConverter expects a getFactory method which is used to initialize the custom converter factory
	extern "C"
	BOOST_EXTENSION_EXPORT_DECL MMM::ConverterFactoryPtr getFactory() {
	MMM::MyConverterFactoryPtr f(new MMM::MyConverterFactory());
	return f;
	}
	\endcode
*/
class MMM_IMPORT_EXPORT ConverterFactory  : public AbstractFactoryMethod<ConverterFactory, void*>
{
public:

	ConverterFactory() {;}
	virtual ~ConverterFactory() {;}

	virtual ConverterPtr createConverter() = 0;

};

typedef boost::shared_ptr<ConverterFactory> ConverterFactoryPtr;


} // namespace MMM

#endif // _MMM_ConverterFactory_h_
